/*
 * C++11 新特性演示
 * 本文件展示了 C++11 标准引入的主要新特性
 * 编译命令: g++ -std=c++11 -pthread 4.新特性.cc -o cpp11_features
 */

#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <array>
#include <unordered_map>
#include <tuple>
#include <algorithm>
#include <functional>
#include <initializer_list>
#include <type_traits>

// ============================================================================
// 1. auto 关键字和类型推导
// ============================================================================
void demo_auto_keyword() {
    std::cout << "\n=== 1. auto 关键字演示 ===\n";
    
    // 基本类型推导
    auto i = 42;                    // int
    auto d = 3.14;                  // double
    auto s = std::string("Hello");  // std::string
    auto v = std::vector<int>{1, 2, 3, 4, 5};  // std::vector<int>
    
    std::cout << "auto i = " << i << " (type: int)\n";
    std::cout << "auto d = " << d << " (type: double)\n";
    std::cout << "auto s = " << s << " (type: std::string)\n";
    
    // 迭代器类型推导
    for (auto it = v.begin(); it != v.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << "\n";
    
    // decltype 演示
    decltype(i) j = 100;  // j 的类型与 i 相同 (int)
    decltype(d + i) result = d + i;  // result 类型为 double
    
    std::cout << "decltype(i) j = " << j << "\n";
    std::cout << "decltype(d + i) result = " << result << "\n";
}

// ============================================================================
// 2. nullptr 和空指针
// ============================================================================
void demo_nullptr() {
    std::cout << "\n=== 2. nullptr 演示 ===\n";
    
    // C++11 之前使用 NULL 或 0
    int* old_ptr = NULL;
    
    // C++11 使用 nullptr
    int* new_ptr = nullptr;
    std::unique_ptr<int> smart_ptr = nullptr;
    
    std::cout << "old_ptr (NULL): " << old_ptr << "\n";
    std::cout << "new_ptr (nullptr): " << new_ptr << "\n";
    std::cout << "smart_ptr: " << (smart_ptr ? "not null" : "null") << "\n";
    
    // nullptr 的类型安全性
    auto check_null = [](std::nullptr_t) {
        std::cout << "接收到 nullptr\n";
    };
    check_null(nullptr);
}

// ============================================================================
// 3. 范围 for 循环 (Range-based for loop)
// ============================================================================
void demo_range_based_for() {
    std::cout << "\n=== 3. 范围 for 循环演示 ===\n";
    
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::string text = "Hello";
    
    // 基本范围 for 循环
    std::cout << "numbers: ";
    for (const auto& num : numbers) {
        std::cout << num << " ";
    }
    std::cout << "\n";
    
    // 修改元素
    std::cout << "修改后的 numbers: ";
    for (auto& num : numbers) {
        num *= 2;
        std::cout << num << " ";
    }
    std::cout << "\n";
    
    // 字符串遍历
    std::cout << "text 字符: ";
    for (char c : text) {
        std::cout << c << " ";
    }
    std::cout << "\n";
}

// ============================================================================
// 4. 初始化列表 (Initializer List)
// ============================================================================
class InitializerListDemo {
private:
    std::vector<int> data;
    
public:
    // 接受初始化列表的构造函数
    InitializerListDemo(std::initializer_list<int> list) : data(list) {
        std::cout << "使用初始化列表构造，元素个数: " << data.size() << "\n";
    }
    
    void print() const {
        std::cout << "数据: ";
        for (const auto& item : data) {
            std::cout << item << " ";
        }
        std::cout << "\n";
    }
    
    // 接受初始化列表的赋值操作
    InitializerListDemo& operator=(std::initializer_list<int> list) {
        data = list;
        return *this;
    }
};

void demo_initializer_list() {
    std::cout << "\n=== 4. 初始化列表演示 ===\n";
    
    // 统一初始化语法
    std::vector<int> v1{1, 2, 3, 4, 5};
    std::vector<int> v2 = {6, 7, 8, 9, 10};
    
    // 自定义类使用初始化列表
    InitializerListDemo demo{1, 2, 3, 4, 5};
    demo.print();
    
    demo = {10, 20, 30};
    demo.print();
    
    // 内置类型的统一初始化
    int x{42};
    double y{3.14};
    std::cout << "统一初始化: x = " << x << ", y = " << y << "\n";
}

// ============================================================================
// 5. 右值引用和移动语义
// ============================================================================
class MoveDemo {
private:
    std::string* data;
    size_t size;
    
public:
    // 构造函数
    MoveDemo(const std::string& str) : size(1) {
        data = new std::string(str);
        std::cout << "构造函数: " << *data << "\n";
    }
    
    // 拷贝构造函数
    MoveDemo(const MoveDemo& other) : size(other.size) {
        data = new std::string(*other.data);
        std::cout << "拷贝构造函数: " << *data << "\n";
    }
    
    // 移动构造函数 (C++11 新特性)
    MoveDemo(MoveDemo&& other) noexcept : data(other.data), size(other.size) {
        other.data = nullptr;
        other.size = 0;
        std::cout << "移动构造函数: " << (data ? *data : "null") << "\n";
    }
    
    // 拷贝赋值操作符
    MoveDemo& operator=(const MoveDemo& other) {
        if (this != &other) {
            delete data;
            data = new std::string(*other.data);
            size = other.size;
            std::cout << "拷贝赋值: " << *data << "\n";
        }
        return *this;
    }
    
    // 移动赋值操作符 (C++11 新特性)
    MoveDemo& operator=(MoveDemo&& other) noexcept {
        if (this != &other) {
            delete data;
            data = other.data;
            size = other.size;
            other.data = nullptr;
            other.size = 0;
            std::cout << "移动赋值: " << (data ? *data : "null") << "\n";
        }
        return *this;
    }
    
    // 析构函数
    ~MoveDemo() {
        if (data) {
            std::cout << "析构: " << *data << "\n";
            delete data;
        } else {
            std::cout << "析构: 空对象\n";
        }
    }
    
    void print() const {
        if (data) {
            std::cout << "数据: " << *data << "\n";
        } else {
            std::cout << "数据: 空\n";
        }
    }
};

void demo_move_semantics() {
    std::cout << "\n=== 5. 移动语义演示 ===\n";
    
    MoveDemo obj1("Hello World");
    obj1.print();
    
    // 使用 std::move 触发移动语义
    MoveDemo obj2 = std::move(obj1);
    std::cout << "移动后:\n";
    obj1.print();  // obj1 现在为空
    obj2.print();  // obj2 拥有数据
    
    // 移动赋值
    MoveDemo obj3("Temporary");
    obj3 = std::move(obj2);
    std::cout << "移动赋值后:\n";
    obj2.print();  // obj2 现在为空
    obj3.print();  // obj3 拥有数据
}

// ============================================================================
// 6. Lambda 表达式
// ============================================================================
void demo_lambda_expressions() {
    std::cout << "\n=== 6. Lambda 表达式演示 ===\n";
    
    // 基本 lambda
    auto simple_lambda = []() {
        std::cout << "简单 lambda 表达式\n";
    };
    simple_lambda();
    
    // 带参数的 lambda
    auto add = [](int a, int b) -> int {
        return a + b;
    };
    std::cout << "5 + 3 = " << add(5, 3) << "\n";
    
    // 捕获外部变量
    int x = 10;
    int y = 20;
    
    // 按值捕获
    auto capture_by_value = [x, y]() {
        std::cout << "按值捕获: x = " << x << ", y = " << y << "\n";
    };
    capture_by_value();
    
    // 按引用捕获
    auto capture_by_reference = [&x, &y]() {
        x += 5;
        y += 10;
        std::cout << "按引用捕获并修改: x = " << x << ", y = " << y << "\n";
    };
    capture_by_reference();
    
    // 捕获所有变量
    auto capture_all = [=]() mutable {
        x = 100;  // mutable 允许修改按值捕获的变量
        std::cout << "捕获所有(按值): x = " << x << "\n";
    };
    capture_all();
    std::cout << "原始 x 值: " << x << "\n";
    
    // 在算法中使用 lambda
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // 查找偶数
    auto even_count = std::count_if(numbers.begin(), numbers.end(), 
                                   [](int n) { return n % 2 == 0; });
    std::cout << "偶数个数: " << even_count << "\n";
    
    // 排序 (降序)
    std::sort(numbers.begin(), numbers.end(), 
              [](int a, int b) { return a > b; });
    std::cout << "降序排列: ";
    for (int n : numbers) {
        std::cout << n << " ";
    }
    std::cout << "\n";
}

// ============================================================================
// 7. 智能指针
// ============================================================================
class Resource {
private:
    std::string name;
    
public:
    Resource(const std::string& n) : name(n) {
        std::cout << "创建资源: " << name << "\n";
    }
    
    ~Resource() {
        std::cout << "销毁资源: " << name << "\n";
    }
    
    void use() const {
        std::cout << "使用资源: " << name << "\n";
    }
    
    const std::string& getName() const { return name; }
};

void demo_smart_pointers() {
    std::cout << "\n=== 7. 智能指针演示 ===\n";
    
    // unique_ptr - 独占所有权
    {
        std::cout << "--- unique_ptr 演示 ---\n";
        std::unique_ptr<Resource> ptr1 = std::make_unique<Resource>("Resource1");
        ptr1->use();
        
        // 移动所有权
        std::unique_ptr<Resource> ptr2 = std::move(ptr1);
        if (!ptr1) {
            std::cout << "ptr1 现在为空\n";
        }
        ptr2->use();
        
        // 自动释放资源 (离开作用域时)
    }
    
    // shared_ptr - 共享所有权
    {
        std::cout << "\n--- shared_ptr 演示 ---\n";
        std::shared_ptr<Resource> ptr1 = std::make_shared<Resource>("Resource2");
        std::cout << "引用计数: " << ptr1.use_count() << "\n";
        
        {
            std::shared_ptr<Resource> ptr2 = ptr1;  // 共享所有权
            std::cout << "引用计数: " << ptr1.use_count() << "\n";
            ptr2->use();
        }  // ptr2 离开作用域
        
        std::cout << "引用计数: " << ptr1.use_count() << "\n";
        ptr1->use();
    }  // ptr1 离开作用域，资源被释放
    
    // weak_ptr - 弱引用
    {
        std::cout << "\n--- weak_ptr 演示 ---\n";
        std::weak_ptr<Resource> weak_ptr;
        
        {
            std::shared_ptr<Resource> shared_ptr = std::make_shared<Resource>("Resource3");
            weak_ptr = shared_ptr;
            
            if (auto locked = weak_ptr.lock()) {
                std::cout << "通过 weak_ptr 访问资源\n";
                locked->use();
            }
        }  // shared_ptr 离开作用域
        
        if (weak_ptr.expired()) {
            std::cout << "weak_ptr 指向的对象已被销毁\n";
        }
    }
}

// ============================================================================
// 8. 多线程支持
// ============================================================================
std::mutex mtx;
std::condition_variable cv;
std::atomic<bool> ready{false};
std::atomic<int> counter{0};

void worker_thread(int id) {
    // 等待主线程信号
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, [] { return ready.load(); });
    
    // 执行工作
    for (int i = 0; i < 5; ++i) {
        {
            std::lock_guard<std::mutex> guard(mtx);
            std::cout << "线程 " << id << " 执行任务 " << i << "\n";
        }
        counter.fetch_add(1);
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

void demo_threading() {
    std::cout << "\n=== 8. 多线程支持演示 ===\n";
    
    // 创建线程
    std::vector<std::thread> threads;
    for (int i = 0; i < 3; ++i) {
        threads.emplace_back(worker_thread, i + 1);
    }
    
    // 启动所有线程
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;
    }
    cv.notify_all();
    
    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }
    
    std::cout << "所有线程完成，总计数器值: " << counter.load() << "\n";
}

// ============================================================================
// 9. 新容器和数据结构
// ============================================================================
void demo_new_containers() {
    std::cout << "\n=== 9. 新容器演示 ===\n";
    
    // std::array - 固定大小数组
    std::cout << "--- std::array ---\n";
    std::array<int, 5> arr = {1, 2, 3, 4, 5};
    std::cout << "array 大小: " << arr.size() << "\n";
    std::cout << "array 元素: ";
    for (const auto& elem : arr) {
        std::cout << elem << " ";
    }
    std::cout << "\n";
    
    // std::unordered_map - 哈希表
    std::cout << "\n--- std::unordered_map ---\n";
    std::unordered_map<std::string, int> hash_map = {
        {"apple", 5},
        {"banana", 3},
        {"orange", 8}
    };
    
    hash_map["grape"] = 12;
    
    std::cout << "哈希表内容:\n";
    for (const auto& pair : hash_map) {
        std::cout << pair.first << ": " << pair.second << "\n";
    }
    
    // std::tuple - 元组
    std::cout << "\n--- std::tuple ---\n";
    std::tuple<std::string, int, double> person("Alice", 25, 175.5);
    
    std::cout << "姓名: " << std::get<0>(person) << "\n";
    std::cout << "年龄: " << std::get<1>(person) << "\n";
    std::cout << "身高: " << std::get<2>(person) << "\n";
    
    // 结构化绑定 (C++17 特性，这里展示 C++11 的 tie)
    std::string name;
    int age;
    double height;
    std::tie(name, age, height) = person;
    std::cout << "解包后: " << name << ", " << age << ", " << height << "\n";
}

// ============================================================================
// 10. constexpr 和编译时计算
// ============================================================================
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

constexpr int square(int x) {
    return x * x;
}

void demo_constexpr() {
    std::cout << "\n=== 10. constexpr 演示 ===\n";
    
    // 编译时计算
    constexpr int fact5 = factorial(5);
    constexpr int sq10 = square(10);
    
    std::cout << "5! = " << fact5 << " (编译时计算)\n";
    std::cout << "10² = " << sq10 << " (编译时计算)\n";
    
    // 运行时也可以使用
    int n = 6;
    std::cout << n << "! = " << factorial(n) << " (运行时计算)\n";
}

// ============================================================================
// 11. static_assert 编译时断言
// ============================================================================
template<typename T>
class TypeChecker {
    static_assert(std::is_arithmetic<T>::value, "T 必须是算术类型");
    
private:
    T value;
    
public:
    TypeChecker(T v) : value(v) {}
    T getValue() const { return value; }
};

void demo_static_assert() {
    std::cout << "\n=== 11. static_assert 演示 ===\n";
    
    // 这些会编译成功
    TypeChecker<int> int_checker(42);
    TypeChecker<double> double_checker(3.14);
    
    std::cout << "int_checker 值: " << int_checker.getValue() << "\n";
    std::cout << "double_checker 值: " << double_checker.getValue() << "\n";
    
    // 下面这行如果取消注释会导致编译错误
    // TypeChecker<std::string> string_checker("hello");  // 编译错误
    
    std::cout << "static_assert 确保类型安全\n";
}

// ============================================================================
// 12. override 和 final 关键字
// ============================================================================
class Base {
public:
    virtual void func1() {
        std::cout << "Base::func1()\n";
    }
    
    virtual void func2() {
        std::cout << "Base::func2()\n";
    }
    
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    // override 确保正确重写虚函数
    void func1() override {
        std::cout << "Derived::func1()\n";
    }
    
    // final 防止进一步重写
    void func2() override final {
        std::cout << "Derived::func2() - final\n";
    }
};

// final 类不能被继承
class FinalClass final {
public:
    void method() {
        std::cout << "FinalClass::method()\n";
    }
};

void demo_override_final() {
    std::cout << "\n=== 12. override 和 final 演示 ===\n";
    
    std::unique_ptr<Base> ptr = std::make_unique<Derived>();
    ptr->func1();  // 调用 Derived::func1()
    ptr->func2();  // 调用 Derived::func2()
    
    FinalClass final_obj;
    final_obj.method();
    
    std::cout << "override 确保虚函数正确重写，final 防止进一步继承/重写\n";
}

// ============================================================================
// 13. 委托构造函数和默认/删除函数
// ============================================================================
class DelegatingConstructor {
private:
    int value;
    std::string name;
    
public:
    // 主构造函数
    DelegatingConstructor(int v, const std::string& n) : value(v), name(n) {
        std::cout << "主构造函数: " << name << " = " << value << "\n";
    }
    
    // 委托构造函数
    DelegatingConstructor(int v) : DelegatingConstructor(v, "默认名称") {
        std::cout << "委托构造函数完成\n";
    }
    
    // 默认构造函数
    DelegatingConstructor() : DelegatingConstructor(0) {
        std::cout << "默认构造函数完成\n";
    }
    
    // 显式默认拷贝构造函数
    DelegatingConstructor(const DelegatingConstructor&) = default;
    
    // 显式删除赋值操作符
    DelegatingConstructor& operator=(const DelegatingConstructor&) = delete;
    
    void print() const {
        std::cout << "对象: " << name << " = " << value << "\n";
    }
};

void demo_delegating_constructors() {
    std::cout << "\n=== 13. 委托构造函数演示 ===\n";
    
    DelegatingConstructor obj1;
    obj1.print();
    
    DelegatingConstructor obj2(42);
    obj2.print();
    
    DelegatingConstructor obj3(100, "自定义名称");
    obj3.print();
    
    // 下面这行会导致编译错误，因为赋值操作符被删除
    // obj1 = obj2;  // 编译错误
    
    std::cout << "委托构造函数简化了构造逻辑\n";
}

// ============================================================================
// 主函数 - 演示所有特性
// ============================================================================
int main() {
    std::cout << "C++11 新特性全面演示\n";
    std::cout << "====================\n";
    
    try {
        demo_auto_keyword();
        demo_nullptr();
        demo_range_based_for();
        demo_initializer_list();
        demo_move_semantics();
        demo_lambda_expressions();
        demo_smart_pointers();
        demo_threading();
        demo_new_containers();
        demo_constexpr();
        demo_static_assert();
        demo_override_final();
        demo_delegating_constructors();
        
        std::cout << "\n=== 所有 C++11 新特性演示完成 ===\n";
        
    } catch (const std::exception& e) {
        std::cerr << "异常: " << e.what() << "\n";
        return 1;
    }
    
    return 0;
}

/*
 * 编译和运行说明:
 * 
 * 1. 编译命令:
 *    g++ -std=c++11 -pthread -O2 4.新特性.cc -o cpp11_features
 * 
 * 2. 运行:
 *    ./cpp11_features
 * 
 * 3. 主要 C++11 特性总结:
 *    - auto 关键字: 自动类型推导
 *    - nullptr: 类型安全的空指针
 *    - 范围 for 循环: 简化容器遍历
 *    - 初始化列表: 统一初始化语法
 *    - 右值引用和移动语义: 提高性能
 *    - Lambda 表达式: 函数式编程支持
 *    - 智能指针: 自动内存管理
 *    - 多线程支持: 标准库线程支持
 *    - 新容器: array, unordered_map, tuple
 *    - constexpr: 编译时计算
 *    - static_assert: 编译时断言
 *    - override/final: 虚函数控制
 *    - 委托构造函数: 构造函数重用
 *    - 默认/删除函数: 精确控制特殊成员函数
 * 
 * 这些特性大大提升了 C++ 的表达能力、性能和安全性。
 */